package com.naiterui.ehp.bs.pharmacist.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import com.naiterui.common.redis.RedisUtil;
import com.naiterui.ehp.bp.bo.esign.DigitalCertificateBO;
import com.naiterui.ehp.bp.bo.esign.EsignNoSecretBO;
import com.naiterui.ehp.bp.bo.esign.PreSignResultBO;
import com.naiterui.ehp.bp.constants.CommonConstant;
import com.naiterui.ehp.bp.constants.SwaggerTag;
import com.naiterui.ehp.bp.support.exception.BaseExceptionCodes;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.support.exception.PublicService;
import com.naiterui.ehp.bp.support.exception.ResponseVO;
import com.naiterui.ehp.bs.pharmacist.exception.ExceptionCodes;
import com.naiterui.ehp.bs.pharmacist.service.IEsignUserService;
import com.naiterui.ehp.bs.pharmacist.utils.SealImageUtil;
import com.naiterui.ehp.bs.pharmacist.vo.esign.WillTypeVO;

import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;


/**
 * @Description 电子签名用户设置
 * @Author gongbaoqiang
 * @Date 2020/6/9 10:37 AM
 */
@Api(tags = {SwaggerTag.PHARMACIST + SwaggerTag.CA_ESIGN})
@Slf4j
@RestController
@RequestMapping("pharmacist/esign/user")
public class PharmacistESignUserController {

    @Autowired
    private IEsignUserService userService;

    /**
     * <获取实名认证验证码>
     * 
     * @param pharmacistId
     * @deprecated 业务流程调整，该接口移至{@link PharmacistLoginController#realnameCode(String)}
     * @return
     * @throws BusinessException
     */
    @Deprecated
    @ResponseBody
    @PostMapping("realname/code")
    @ApiOperation(value = "获取实名认证验证码", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pharmacistId", value = "药师id", required = true, dataType = "long") })
    public ResponseVO<Void> realnameCode(Long pharmacistId) throws BusinessException {

        log.info("获取实名认证验证码 请求参数：pharmacistId = [{}]", pharmacistId);

        userService.getRealnameCode(pharmacistId);

        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);

    }

    /**
     * <实名认证验证码>
     * 
     * @param pharmacistId
     * @deprecated 业务流程调整，该接口移至{@link PharmacistLoginController#realnameCheck(String,String)}
     * @return
     * @throws BusinessException
     */
    @Deprecated
    @ResponseBody
    @PostMapping("realname/check")
    @ApiOperation(value = "实名认证", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pharmacistId", value = "药师ID", required = true, dataType = "long"),
            @ApiImplicitParam(name = "code", value = "验证码", required = true, dataType = "string") })
    public ResponseVO<Void> realnameCheck(Long pharmacistId, String code) throws BusinessException {

        log.info("实名认证 请求参数：pharmacistId = [{}], code={}", pharmacistId, code);

        userService.checkRealnameCode(pharmacistId, code);

        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);

    }


    /**
     * <获取签署方式列表>
     * @return
     * @throws BusinessException
     */
    @PostMapping("will/types")
    @ApiOperation(value = "获取签署方式列表", httpMethod = "POST")
    public ResponseVO<List<WillTypeVO>> willTypes(Long pharmacistId) throws BusinessException {

        log.info("药师获取签署方式列表：pharmacistId={}", pharmacistId);

        return PublicService.returnResponseVO(userService.getWillTypes(pharmacistId));

    }

    /**
     * <保存药师愿签署方式>
     * @param pharmacistId
     * @return
     * @throws BusinessException
     */
    @PostMapping("will/type/save")
    @ApiOperation(value = "保存药师愿签署方式", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pharmacistId", value = "医生id", required = true, dataType = "long"),
            @ApiImplicitParam(name = "willType", value = "签署方式", required = true, dataType = "string") })
    public ResponseVO<Void> saveWillType(Long pharmacistId, String willType) throws BusinessException {

        log.info("保存药师愿签署方式 请求参数：pharmacistId = [{}], willType={}", pharmacistId, willType);

        userService.updateWillType(pharmacistId, willType);

        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);

    }


    /**
     * <设置签名密码>
     * @param pharmacistId
     * @return
     * @throws BusinessException
     */
    @PostMapping("password/set")
    @ApiOperation(value = "设置签名密码", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pharmacistId", value = "医生id", required = true, dataType = "long"),
            @ApiImplicitParam(name = "passwd", value = "签名密码", required = true, dataType = "string"),
            @ApiImplicitParam(name = "code", value = "短信验证码", required = true, dataType = "string"),
    })
    public ResponseVO<Void> setPassword(Long pharmacistId, String passwd, String code) throws BusinessException {

        log.info("获取实名认证验证码 请求参数：pharmacistId = [{}], passwd={}, code={}", pharmacistId, passwd, code);

        userService.updatePassword(pharmacistId, passwd, code);

        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);

    }

    /**
     * <是否已设置签名密码>
     * @param pharmacistId
     * @return
     * @throws BusinessException
     */
    @PostMapping("password/set/status")
    @ApiOperation(value = "是否已设置签名密码", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pharmacistId", value = "药师id", required = true, dataType = "long")
    })
    public ResponseVO<Boolean> passwordStatus(Long pharmacistId) throws BusinessException {

        log.info("药师是否已设置签名密码 请求参数：pharmacistId = [{}]", pharmacistId);

        return PublicService.returnResponseVO(userService.passwordStatus(pharmacistId));

    }

    @GetMapping("sign/license")
    @ApiOperation(value = "查看签名图片", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pharmacistId", value = "药师ID", required = true, dataType = "long") })
    public ResponseVO<String> signLicense(@RequestParam Long pharmacistId) throws BusinessException {
        log.info("查看签名图片 请求参数：pharmacistId= {},", pharmacistId);
        return PublicService.returnResponseVO(userService.signLicense(pharmacistId));
    }

    @GetMapping("/getNoSecret")
    @ApiOperation("获取免密状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pharmacistId", value = "药师id", required = true, dataType = "long")
    })
    public ResponseVO<EsignNoSecretBO> getNoSecret(Long pharmacistId) throws BusinessException {
        log.info("获取免密状态：pharmacistId={}", pharmacistId);
        EsignNoSecretBO noSecretBO = userService.getNoSecretByPharmacistId(pharmacistId);
        log.info("获取免密结果：{}", JSONUtil.toJsonStr(noSecretBO));
        return PublicService.returnResponseVO(noSecretBO);
    }

    @PostMapping("/preNoSecret")
    @ApiOperation("免密预签署")
    @ApiImplicitParams({@ApiImplicitParam(name = "pharmacistId", value = "药师id", required = true, dataType = "long")})
    public ResponseVO<PreSignResultBO> preNoSecret(Long pharmacistId) throws BusinessException {
        log.info("免密预签署：doctorId={}", pharmacistId);
        return PublicService.returnResponseVO(userService.preNoSecret(pharmacistId));
    }

    @PostMapping("/setNoSecret")
    @ApiOperation("设置免密")
    @ApiImplicitParams({@ApiImplicitParam(name = "pharmacistId", value = "药师id", required = true, dataType = "long"),
        @ApiImplicitParam(name = "noSecret", value = "免密 true开通 false关闭", required = true, dataType = "boolean"),
        @ApiImplicitParam(name = "authPwd", value = "签名密码, noSecret为false可以为空", dataType = "string"),
        @ApiImplicitParam(name = "uniqueId", value = "唯一标识, noSecret为false可以为空", dataType = "string")
    })
    public ResponseVO<Void> setNoSecret(Long pharmacistId, Boolean noSecret, String authPwd, String uniqueId)
        throws BusinessException {
        log.info("设置免密：pharmacistId={}, authPwd={}", pharmacistId, authPwd);
        if(pharmacistId == null || noSecret == null){
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        if (noSecret && uniqueId == null) {
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        userService.setNoSecret(pharmacistId, noSecret, authPwd, uniqueId);
        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);
    }

    @PostMapping("/notRemind")
    @ApiOperation("不提醒")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pharmacistId", value = "药师id", required = true, dataType = "long")
    })
    public ResponseVO<Void> notRemind(Long pharmacistId) throws BusinessException {
        log.info("免密7天不提醒：pharmacistId={}", pharmacistId);
        if (pharmacistId == null) {
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        // 存入7天不提醒
        RedisUtil.valueOps().setString(CommonConstant.PH_NO_SECRET_REMIND + pharmacistId, "1", 7 * 24 * 3600);
        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);
    }

    @GetMapping("/getDigitalCertificate")
    @ApiOperation("获取药师数字证书")
    @ApiImplicitParam(name = "pharmacistId", value = "药师id", required = true, dataType = "long")
    private DigitalCertificateBO getDigitalCertificate(@RequestParam Long pharmacistId) throws BusinessException {
        return userService.getDigitalCertificate(pharmacistId);
    }

    /**
     * 生成签章图
     *
     * @param pharmacistId
     * @param name
     * @return
     */
    @GetMapping("seal/generation")
    @ApiOperation(value = "生成姓名签章图base64")
    @ApiImplicitParams({@ApiImplicitParam(name = "pharmacistId", value = "药师id", required = true, dataType = "long"),
        @ApiImplicitParam(name = "name", value = "姓名", required = true, dataType = "String")})
    public ResponseVO<String> sealGeneration(Long pharmacistId, String name) {
        log.info("药师生成姓名签章 请求参数：pharmacistId = [{}], name = [{}]", pharmacistId, name);
        return PublicService.returnResponseVO(SealImageUtil.graphicsNameSealGeneration(name));
    }
}
